home *** CD-ROM | disk | FTP | other *** search
- #pragma once
- //
- // screenarea is a prototypal class for a screen area on the mac.
- // It represents a square area of size x size pixels. After creating a
- // screenarea one can set pixels on the screen via operator[]. An example:
- //
- // screenarea screen( 8);
- // screen.fill();
- // screen[ 3][ 3] = 34;
- //
- // The screenarea is always allocated on the main screen, and it is assumed
- // that that screen is currently in 256-color mode. Furthermore element [ 0][ 0]
- // is not located in a corner of the square, but in the center (well, almost in
- // the center. One can index the rows of the array by going from -(size / 2)
- // up to, but not including size - (size / 2)).
- // For reasons of speed no bounds checking is implemented. It is possible
- // to create a screenarea which is higher than the main screen without any
- // problems, though (but not to create one which is wider than the main screen)
- //
- // As long as the image bounds on screen are OK it is safe to access the array
- // with indices which are reasonably close to the really intended ones. The
- // maximum outward offset allowed is screenarea::max_error. This constant also
- // determines the maximum half_disparity allowed in 'screendots' (v.i)
- //
- // 941027: discovered a serious flaw in this hack while implementing 'FormExp'
- // The remark regarding 'reasonably close to' is only valid regarding the array's
- // x coordinates. BTW: this also means that 'add_big_dot' should not be called
- // for dot positions outside the main screen.
- //
- // 941028: There may be some problems writing outside the 'visible screen area'
- // with screenareas close to the height of the screen or higher than the screen
- // when one uses the offsets returned by 'compass2offsets'. On a SuperMac
- // Spectrum/8 Series II video card it was found that writing outside the screen
- // caused changes in the color look-up table.
- //
- class screenarea
- {
- public:
-
- typedef enum screen_position
- {
- centered, left_side, right_side
- };
-
- screenarea( int numbits, int xpos, int ypos);
- screenarea( int numbits, screen_position where = centered);
-
- ~screenarea();
-
- int any_x() const;
- int any_y() const;
-
- unsigned char *operator[]( const int index);
- //
- // add_circular_mask makes assumptions about the current color environment
- // 'Try before you buy'. 941027: This also applies to 'add_rectangular_mask'
- // 941123: Nowadays, the recommended way to obtain masks is by using simple
- // Macintosh toolbox calls. 'fullscreen::fullscreen' can now make _all_
- // colors associated with a window pmExplicit, so one can use
- //
- // PmForeColor( 74);
- // PaintRect( &rect_to_fill_with_74s);
- //
- // to fill an area of the screen with the value '74'
- //
- void add_circular_mask( void);
- void add_rectangular_mask( int mask_size);
- void fill( const int value = 0);
- void no_mask();
- void add_fixation_dot( const int disparity = 0);
- void add_stereo_cues( const int disparity = 0);
- //
- // compass2offsets takes a string containing zero or more dots and/or a
- // series of letters denoting compass directions
- // and turns it into a series of screen offsets.
- // Every character of the string denotes a step in a state machine:
- //
- // eswn : move a single pixel in the indicated direction
- // ESWN : include the offset of the current pixel in the list,
- // then move a single pixel in the indicated direction.
- // . : include the offset of the current pixel in the list, do not move.
- // (the dot is included for human interface reasons. Generally one can replace
- // .x by X, but .x may be easier to comprehend for some ('.e' shows
- // the order 'set dot, then move', whereas 'E' doesn't)
- //
- // compass2offsets returns both a list of offsets and an integer denoting
- // the length of that list. The 'maxnum' parameter is also used as input
- // to signal the length of the 'offsets' array. As a special case one can
- // pass zero to offsets. In that case maxnum is set to the size 'offsets'
- // needs to have in order to accomodate the list specified by 'compass'.
- // maxnum is always set to the actual number of offsets needed, but the
- // offsets array is never filled with more offsets than were specified
- // in the *maxnum parameter.
- //
- // Examples:
- // .e.s.w. creates 2x2 square dots to the bottom-right of the 'real' dot
- // .e.n.w. creates 2x2 square dots to the top-right of the 'real' dot
- //
- // ww.e.e.e.e.
- // wwEEEE.
- // wwEEEEN these all create 5x1 bars centered at the dot position
- // 2w4E.
- // 12w10e4E.
- //
- void compass2offsets( const char *compass, int *offsets, int *maxnum);
-
- protected:
- const int size;
- const int half_size;
- const int shiftbits;
- const int coord_shift;
- //
- // 940823: compass2offsets needs to know rowBytes => it no longer is
- // a local variable in 'init'. Instead it gets set by init.
- //
- int rowBytes;
- //
- // screen row pointers:
- //
- unsigned char **screen;
- unsigned char *waste_area;
-
- static const int max_error;
- void init( int xpos, int ypos);
-
- private:
- //
- // add_big_dot has not been debugged. It seems to work for use by
- // add_fixation_dot and add_stereo_cues.
- //
- void add_big_dot( const int x, const int y, const int disparity = 0);
- };
-
- inline unsigned char * screenarea::operator[]( const int index)
- {
- return screen[ index];
- }
-
- inline screenarea::screenarea( int numbits, int xpos, int ypos)
- : size( 1 << numbits)
- , half_size( 1 << (numbits - 1))
- , shiftbits( 2 * numbits - 9)
- , coord_shift( 16 - numbits)
- {
- init( xpos, ypos);
- }
-
- inline void screenarea::no_mask()
- {
- fill( 128);
- }
-
- inline int screenarea::any_x() const
- {
- return (randomizer_step() % size) - half_size;
- }
-
- inline int screenarea::any_y() const
- {
- return (randomizer_step() % size) - half_size;
- }
-